#include "VTranslation.h"
#include <qfileinfo.h>
#include <qdebug.h>
#include <qtextstream.h>

#include "VFunctions.h"

QMap<QString, QString> * VTranslation::_map = nullptr;
QMap<QString, QString> * VTranslation::_ch_en_map = nullptr;

VTranslation::VTranslation(QString text, QMap<QString, QString> *map)
{
	_document = text;
	VTranslation::_map = map;

	if (_ch_en_map == nullptr)
	{
		_ch_en_map = new QMap<QString, QString>;
		_ch_en_map->insert("短整型", "short");
		_ch_en_map->insert("整数型", "int");
		_ch_en_map->insert("长整型", "long");
		_ch_en_map->insert("小数型", "float");
		_ch_en_map->insert("双精度小数型", "double");
		_ch_en_map->insert("字符型", "char");
		_ch_en_map->insert("结构", "struct");
		_ch_en_map->insert("联合", "union");
		_ch_en_map->insert("枚举", "enum");
		_ch_en_map->insert("类型定义", "typedef");
		_ch_en_map->insert("只读", "const");
		_ch_en_map->insert("无符号", "unsigned");
		_ch_en_map->insert("有符号", "signed");
		_ch_en_map->insert("返回", "return");
		_ch_en_map->insert("引入", "include");
		_ch_en_map->insert("外部引入", "extern");
		_ch_en_map->insert("寄存器", "register");
		_ch_en_map->insert("静态", "static");
		_ch_en_map->insert("易变的", "volatile");
		_ch_en_map->insert("无类型", "void");
		_ch_en_map->insert("如果", "if");
		_ch_en_map->insert("否则", "else");
		_ch_en_map->insert("跳出", "break");
		_ch_en_map->insert("宏定义", "define");
		_ch_en_map->insert("默认", "default");
		_ch_en_map->insert("true", "1");
		_ch_en_map->insert("false", "0");
		_ch_en_map->insert("真", "1");
		_ch_en_map->insert("假", "0");
		_ch_en_map->insert("主函数", "main");
		_ch_en_map->insert("高级循环", "for");
	}
}

VTranslation::~VTranslation()
{
}

QString VTranslation::word_to_englisth(QString word)
{
	QString result;
	if (_ch_en_map->contains(word))
	{
		result = _ch_en_map->value(word);
	}
	else
	{
		if (is_chinese(word))
		{
			result = to_englisth(word);
		}
		else
		{
			result = word;
		}
	}
	
	return result;
}

bool VTranslation::is_chinese(QString word)
{
    foreach (QChar c, word)
	{
		ushort uni = c.unicode();
		if (uni >= 0x4E00 && uni <= 0x9FA5)
		{
			return true;
		}
	}
	return false;
}

QString VTranslation::next_block_str()
{
	if (_pos > _document_length)
	{
		return "";
	}

	QString result = "";
	for (size_t i = _pos; i < _document_length; i++)
	{
		if (is_legal_char(_document.at(i)))
		{
			result += _document.at(i);
		}
		else
		{
			if (result.length() == 0)
			{
				result = _document.at(i);
				_pos++;
				return result;
			}
			else
			{
				_pos = i;
				return result;
			}
		}
	}

	_pos = _document_length;
	return result;
}

bool VTranslation::is_legal_char(QChar c)
{
	int unicode = c.unicode();
	// _ 下划线 ascall 95
	if (unicode > 127 || c.isDigit() || c.isLetter() || unicode == 95)
	{
		return true;
	}
	return false;
}

QString VTranslation::to_englisth(QString text)
{
	QString result;

	auto func1 = [](QString text)-> QString {
		int result = 0;
		//for each (QChar chr in text)
		//{
		//	result %= chr.unicode();
		//}
		return QString::number(text.at(0).unicode());
	};

	auto func2 = [](QString text)-> QString {
		auto abs = [](int n)-> int {
			if (n < 0)
			{
				n = -n;
			}
			return n;
		};

		static unsigned numbits_lookup_table[256] = {
				0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2,
				3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3,
				3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3,
				4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4,
				3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5,
				6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4,
				4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,
				6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5,
				3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3,
				4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6,
				6, 7, 6, 7, 7, 8
		};

		int result = 0;
		std::string str = text.toStdString();
		int str_length = str.length();
		for (int i = 0; i < str_length; i++)
		{
			result += numbits_lookup_table[abs(str.at(i))];
		}
		return QString::number(result);
	};

	auto func3 = [](QString text)-> QString {
		int result = 0;
        foreach (QChar chr, text)
		{
			result += chr.unicode();
		}
		return QString::number(result);
	};

	result = "Q" + func1(text) + func2(text) + func3(text);

	if (_map != nullptr)
	{
		_map->insert(result, text);
	}

	return result;
}

bool VTranslation::save_to_path(QString file_name, QString path, QString source_path)
{
	// 判断保存后缀
	QString save_sufix;
	QString sufix = QFileInfo(file_name).suffix();
	if (sufix == "qh" || sufix == "h")
	{
		save_sufix = "h";
	}
	else if (sufix == "qc" || sufix == "c")
	{
		save_sufix = "c";
	}

	// 转译需求判断
	QString out_text;
	if (sufix.indexOf("q") == -1)
	{
		out_text = _document;
	}
	else
	{
		// 头文件预处理
		QRegExp reg("#(include|引入)(\\s+).([\u4e00-\u9fa5_.a-zA-Z0-9]+).");
		int reg_pos = reg.indexIn(_document, 0);
		while (reg_pos > -1)
		{
			QString replace_str;
			QString str = reg.cap(3);
			replace_str = "";
			if (str.indexOf(".q") != -1)
			{
				replace_str = reg.cap(0).replace(".q", ".");
				_document = _document.replace(reg_pos, reg.cap(0).length(), replace_str);
			}

			reg_pos = reg.indexIn(_document, reg_pos + reg.cap(0).length());
		}

		_document_length = _document.length();
		_pos = 0;
		while (_pos < _document_length)
		{
			QString block_str = next_block_str();
			out_text += word_to_englisth(block_str);
		}
	}

	QString save_path = path + "/" + word_to_englisth(QFileInfo(file_name).baseName()) + "." + save_sufix;
	_map->insert(save_path, source_path);

	QFile file(save_path);
	if (file.exists() == false)
	{
		VFunctions::creat_file(save_path);
	}

	if (file.open(QFile::WriteOnly) == false)
	{
		qDebug() << " VTranslation::save_to_path(QString file_name, QString path)" << endl
			<< "save open file error -> path:" << save_path;
	}
	
	QTextStream out(&file);
	out.setCodec("utf-8");
	out << out_text;
	file.close();

	return false;
}
